#pragma once
#include "common.hpp"
#include "robot_fifo.hpp"
#include "sysapi.hpp"
#include "robot_list.hpp"
#include "can_msg.hpp"

/**
 * @brief 
 */
class robot_can_bus:private robot_driver
{
    friend class robot_can_dev;

    /* CAN硬件接受服务线程 */
    friend void hw_rx_thread_entry(void *p);

    /* CAN硬件接受中断回调函数 */
    friend rt_err_t can_rx_call(rt_device_t dev, rt_size_t size);

    /* 发送服务线程 */
    friend void service_thread_entry(void *p);

public: 
    /* */
    static robot_can_bus* instance();

private:

    static robot_can_bus* p;

    robot_can_bus(const char* name);
    virtual ~robot_can_bus();

    /**
     * @brief 需要在创建之后打开设备
     */
    void open();

    rt_thread_t send_service_thread;
    rt_thread_t hw_rx_thread;

    /* CAN硬件接受信号量 由中断回调函数释放 */
    struct rt_semaphore hw_rx_sem;

    /* 发送信号量 由挂在的设备释放 */
    struct rt_semaphore s_sem;

    /* 消息存储 */
    robot_fifo<can_msg> msg_f;

    /* 挂载设备列表 */
    robot_list* head;
};

